home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 1
/
Nebula One.iso
/
Financial
/
Stopwatch2.3
/
Source
/
ClientInspector.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
9KB
|
411 lines
/*
* For legal stuff see the file COPYRIGHT
*/
#import "ClientInfo.h"
#import "ClientInspector.h"
#import "SessionEditor.h"
#import "ExpenseEditor.h"
#import "Controller.h"
@interface ClientInspector(PRIVATE)
- enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag;
- (void)enableAdd:(BOOL)flag;
- (void)enableModify:(BOOL)flag;
- (void)enableDelete:(BOOL)flag;
- (void)enableUndelete:(BOOL)flag;
- showView:newView mgr:(ViewMgr *)mgr;
- (void)updateButtons;
@end
@implementation ClientInspector
/*
* Allow only one ClientInspector object to be created.
*/
+ sharedInstance
{
static id obj;
if ( ! obj ) {
obj = [[ClientInspector alloc] init];
[NXApp loadNibSection:"ClientInspector.nib" owner:obj withNames:NO];
}
return obj;
}
+ (void)updateButtons
{
[[self sharedInstance] updateButtons];
}
- awakeFromNib
{
NXRect frameRect;
if (![popUpList isKindOf:[PopUpList class]])
popUpList = [popUpButton target];
[currentView getFrame:&frameRect];
[[sessionView removeFromSuperview] setFrame:&frameRect];
[[expenseView removeFromSuperview] setFrame:&frameRect];
[[clientView removeFromSuperview] setFrame:&frameRect];
[[panel contentView] replaceSubview:currentView with:sessionView];
currentView = sessionView;
[viewsPanel free];
[panel setFrameAutosaveName:"ClientInspector"];
[self windowDidResize:panel]; /* make swap views adjust to saved size */
[browser setDoubleAction:@selector(browserDoubleClick:)];
controller = [NXApp delegate];
[self decacheBrowser]; /* requires 'controller' to be set first... */
[[browser matrixInColumn:0] selectCellAt:0 :0];
return self;
}
- (void)decacheBrowser
{
ClientInfo *info = [self selectedClient]; /* remember the selection */
[[controller clientList] sort]; /* in case the name was modified */
[browser loadColumnZero]; /* redisplay */
[self selectClient:info]; /* reinstate the selection */
}
/*
* This may be obsolete...
*/
- display
{
List *clientList = [controller clientList];
/*
* If there are no clients, force the display the Client View,
* since it's the only meaningful one.
*/
if ( [clientList count] == 0 )
[self showClient:nil];
[currentMgr mgrShow:self];
[self updateButtons];
[panel makeKeyAndOrderFront:nil]; /* was just "orderFront:" */
return self;
}
- (void)selectClientAt:(int)row
{
Matrix *matrix = [browser matrixInColumn:0];
[matrix selectCellAt:row :0];
}
- selectClient:(ClientInfo *)info
{
id matrix = [browser matrixInColumn:0];
List *clientList = [controller clientList];
int i = [clientList indexOf:info];
[matrix selectCellAt:i :0];
return self;
}
- addClient:(ClientInfo *)info
{
List *clientList = [controller clientList];
[clientList addObjectIfAbsent:info];
[self decacheBrowser];
[controller decacheBrowser];
[self selectClient:info];
return self;
}
/*
* Generic delete button - invoke the delete method of the
* currently selected view. If the return value is non-nil,
* we save the modified data structure to disk.
*/
- delete:sender
{
if ( [currentMgr mgrDelete:self] ) {
[controller saveClientInfo];
[self updateButtons];
}
return self;
}
- undelete:sender
{
if ( [currentMgr mgrUndelete:self] ) {
[controller saveClientInfo];
[self updateButtons];
}
return self;
}
- add:sender
{
if ( [currentMgr mgrAdd:self] ) {
[controller saveClientInfo];
[self updateButtons];
}
return self;
}
- modify:sender
{
if ( [currentMgr mgrModify:self] ) {
[controller saveClientInfo];
[self updateButtons];
}
return self;
}
- (void)performAdd
{
[addButton performClick:self];
}
- (void)performModify
{
[modifyButton performClick:self];
}
/*
* Called when the client is selected in the inspector's top browser
*/
- browserClick:sender
{
[currentMgr mgrShow:self];
[self updateButtons];
return self;
}
- browserDoubleClick:sender
{
if ( [currentMgr mgrDoubleClick:self] ) {
[controller saveClientInfo];
[self updateButtons];
}
return self;
}
/*
* Called by the Client mgr when the delete button is pressed.
*/
- (ClientInfo *)deleteSelectedClient
{
List *clientList = [controller clientList];
ClientInfo *info = [clientList removeObject:[self selectedClient]];
[self decacheBrowser];
[controller decacheBrowser];
return info;
}
- (ClientInfo *)selectedClient
{
id matrix = [browser matrixInColumn:0];
List *clientList = [controller clientList];
return [clientList objectAt:[matrix selectedRow]];
}
/*
* Called when a new session has been added via the main control panel.
* This allows the browser to update if necessary.
*/
- updatedInfo:info
{
if ( info == [self selectedClient] )
[currentMgr mgrShow:self]; /* force redisplay */
return self;
}
/*
* Delegated methods of NXBrowser
*/
- (int)browser:sender fillMatrix:matrix inColumn:(int)column
{
List *clientList = [controller clientList];
int i, count = [clientList count];
const char *name;
id cell;
for ( i = 0; i < count; i++ ) {
[matrix addRow];
name = [[clientList objectAt:i] clientName];
cell = [matrix cellAt:i :0]; /* 1 dimen. matrix: always use col 0! */
[cell setStringValue:name];
[cell setLoaded:YES];
[cell setLeaf:YES];
}
return count ;
}
- (void)closeMonth
{
[sessionMgr forgetDeletions];
[expenseMgr forgetDeletions];
[clientMgr forgetDeletions];
}
/*
* Force button title to the right state. This is necessary
* because PopupLists are a kludge.
*/
- (void)chooseCell:cell
{
[popUpButton setTitle:[cell title]];
[[popUpList itemList] selectCell:cell];
}
- showClient:sender
{
[self chooseCell:clientMenuCell];
[self showView:clientView mgr:clientMgr];
return self;
}
- showHours:sender
{
[self chooseCell:sessionMenuCell];
[self showView:sessionView mgr:sessionMgr];
return self;
}
- showExpenses:sender
{
[self chooseCell:expenseMenuCell];
[self showView:expenseView mgr:expenseMgr];
return self;
}
- setDocEdited:(BOOL)flag
{
[panel setDocEdited:flag];
return self;
}
/*
* Delegated methods of Window
*/
- windowDidResize:sender
{
NXRect frameRect;
[currentView getFrame:&frameRect];
/* Tell the other swap views their new size */
[sessionView setFrame:&frameRect];
[expenseView setFrame:&frameRect];
[clientView setFrame:&frameRect];
return self;
}
@end
@implementation ClientInspector(PRIVATE)
- enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag
{
[controller enableAdd:addFlag];
[controller enableModify:modFlag];
[self enableAdd:addFlag];
[self enableModify:modFlag];
[self enableDelete:delFlag];
[self enableUndelete:[currentMgr canUndelete]];
return self;
}
- showView:newView mgr:(ViewMgr *)mgr
{
[panel disableFlushWindow];
if (newView != currentView) {
/* Bail out if the user want to save their edits */
if ( [currentMgr isEditing] == NO ||
NXRunAlertPanel( [NXApp appName],
"Modified data has not been saved",
"Let me save it!",
"I don't give a hoot", NULL ) != NX_ALERTDEFAULT ) {
[[panel contentView] replaceSubview:currentView with:newView];
currentView = newView;
currentMgr = mgr;
[mgr mgrShow:self];
[self setDocEdited:[mgr isEditing]];
[panel display];
[self updateButtons];
}
}
[[panel reenableFlushWindow] flushWindow];
[panel makeKeyAndOrderFront:nil]; /* was just orderFront: before */
return self;
}
/*
* These are packaged as methods so we can easily add accelerator
* keys that are controlled at the same time...
*/
- (void)enableAdd:(BOOL)flag
{
[addButton setEnabled:flag];
}
- (void)enableModify:(BOOL)flag
{
[modifyButton setEnabled:flag];
}
- (void)enableDelete:(BOOL)flag
{
[controller enableDelete:flag];
[deleteButton setEnabled:flag];
}
/*
* Control the menu item from here...
*/
- (void)enableUndelete:(BOOL)flag
{
[controller enableUndelete:flag];
}
- (void)updateButtons
{
BOOL flag = ([[controller clientList] count] == 0 ? NO : YES);
[self enableAdd:[currentMgr canAdd]
delete:[currentMgr canDelete]
modify:[currentMgr canModify]];
/* Enable these when there are clients */
[sessionMenuCell setEnabled:flag];
[expenseMenuCell setEnabled:flag];
}
/*
* First responder method - pass to view manager
*/
- selectAll:sender
{
if ( [currentMgr respondsTo:@selector(selectAll:)] )
return [currentMgr selectAll:sender];
return nil; /* is this the right thing to do? */
}
@end